package linklisttest;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * 自定义实现一个链表
 * 具备增加节点、删除节点、返回长度和数组等功能
 *
 * @author lzy
 * @create 2018-03-16 上午9:49
 */
public class Link<T> {
    //=================== 以上是内部类 ====================
    private Node root;
    private int count;
    private int foot = 0;
    private Object[] retArray;

    public void add(T data) {
        if (data == null) {
            return;
        } else {
            Node newNode = new Node(data);
            if (this.root == null) {
                root = newNode;
            } else {
                this.root.addNode(newNode);
            }
            this.count++;
        }
    }

    public boolean contains(T data) {
        if (data == null || this.root == null) {
            return false;
        } else {
            return this.root.contains(data);
        }
    }

    public int size() {
        return this.count;
    }

    public boolean isEmpty() {
        return this.count == 0;
    }

    public T getNode(int index) {
        if (index > this.count - 1) {
            return null;
        }
        this.foot = 0;
        return this.root.getNode(index);
    }

    public void set(int index, T data) {
        if (index > this.count - 1) {
            return;
        } else {
            this.foot = 0;
            this.root.setNode(index, data);
        }
    }

    public void remove(T data) {
        if (this.contains(data)) {
            if (data.equals(this.root.data)) {
                this.root = this.root.next;
            } else {
                this.root.next.removeNode(this.root, data);
            }
            this.count--;
        }
    }

    public Object[] toArray() {
        if (this.root == null) {
            return null;
        }
        this.foot = 0;
        this.retArray = new Object[this.count];
        this.root.toArrayNode();
        return this.retArray;
    }

    public void clear() {
        this.root = null;
        this.count = 0;
    }

    private class Node {
        private T data;
        private Node next;

        public Node(T data) {
            this.data = data;
        }

        public void addNode(Node newNode) {
            if (this.next == null) {
                this.next = newNode;
            } else {
                this.next.addNode(newNode);
            }
        }

        public boolean contains(T data) {
            if (data.equals(this.data)) {
                return true;
            } else {
                return this.next != null && this.next.contains(data);
            }
        }

        public T getNode(int index) {
            if (Link.this.foot++ == index) {
                return this.data;
            } else {
                return this.next.getNode(index);
            }
        }

        public void setNode(int index, T data) {
            if (Link.this.foot++ == index) {
                this.data = data;
            } else {
                this.next.setNode(index, data);
            }
        }

        public void removeNode(Node previous, T data) {
            if (data.equals(this.data)) {
                previous.next = this.next;
            } else {
                this.next.removeNode(this, data);
            }
        }

        public void toArrayNode() {
            Link.this.retArray[Link.this.foot++] = this.data;
            if (this.next != null) {
                this.next.toArrayNode();
            }
        }
    }
}
